"""
版本回滚机制 - 快速回滚到稳定版本

这个模块实现了版本回滚功能：
- 版本管理
- 自动回滚
- 回滚策略
- 数据一致性保证
- 回滚监控
"""

import asyncio
import logging
import time
import json
import shutil
from dataclasses import dataclass, field
from datetime import datetime, timezone, timedelta
from enum import Enum
from typing import Any, Dict, List, Optional, Union, Callable, Tuple
from pathlib import Path
import hashlib
import subprocess
import sys

logger = logging.getLogger(__name__)


class VersionStatus(Enum):
    """版本状态"""
    ACTIVE = "active"          # 当前活跃版本
    STABLE = "stable"          # 稳定版本
    DEPRECATED = "deprecated"  # 已弃用版本
    ROLLED_BACK = "rolled_back"  # 已回滚版本
    FAILED = "failed"          # 失败版本


class RollbackStrategy(Enum):
    """回滚策略"""
    IMMEDIATE = "immediate"    # 立即回滚
    GRADUAL = "gradual"        # 逐步回滚
    CANARY = "canary"          # 金丝雀回滚
    BLUE_GREEN = "blue_green"  # 蓝绿部署回滚


class RollbackTrigger(Enum):
    """回滚触发条件"""
    MANUAL = "manual"          # 手动触发
    ERROR_RATE = "error_rate"  # 错误率过高
    RESPONSE_TIME = "response_time"  # 响应时间过长
    HEALTH_CHECK = "health_check"  # 健康检查失败
    METRICS_THRESHOLD = "metrics_threshold"  # 指标阈值


@dataclass
class VersionInfo:
    """版本信息"""
    version_id: str
    version_name: str
    description: str = ""
    
    # 版本元数据
    git_commit: Optional[str] = None
    build_number: Optional[str] = None
    build_time: Optional[datetime] = None
    deployed_at: Optional[datetime] = None
    
    # 版本状态
    status: VersionStatus = VersionStatus.ACTIVE
    is_stable: bool = False
    is_rollback_target: bool = True
    
    # 配置信息
    config_hash: Optional[str] = None
    dependencies: List[str] = field(default_factory=list)
    
    # 性能指标
    error_rate: float = 0.0
    response_time: float = 0.0
    throughput: float = 0.0
    cpu_usage: float = 0.0
    memory_usage: float = 0.0
    
    # 回滚信息
    rollback_count: int = 0
    last_rollback_at: Optional[datetime] = None
    rollback_reason: str = ""
    
    # 元数据
    tags: List[str] = field(default_factory=list)
    created_by: str = "system"
    created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))


@dataclass
class RollbackConfig:
    """回滚配置"""
    # 回滚策略
    default_strategy: RollbackStrategy = RollbackStrategy.IMMEDIATE
    enable_auto_rollback: bool = True
    
    # 触发条件
    error_rate_threshold: float = 0.05  # 5%
    response_time_threshold: float = 2.0  # 2秒
    health_check_failure_threshold: int = 3  # 连续3次失败
    
    # 回滚限制
    max_rollback_attempts: int = 3
    rollback_cooldown: int = 300  # 5分钟冷却期
    
    # 数据一致性
    enable_data_backup: bool = True
    backup_retention_days: int = 7
    enable_data_validation: bool = True
    
    # 监控配置
    enable_rollback_monitoring: bool = True
    monitoring_duration: int = 1800  # 30分钟监控期
    
    # 通知配置
    enable_notifications: bool = True
    notification_recipients: List[str] = field(default_factory=list)


@dataclass
class RollbackRecord:
    """回滚记录"""
    rollback_id: str
    from_version: str
    to_version: str
    strategy: RollbackStrategy
    trigger: RollbackTrigger
    reason: str
    
    # 执行信息
    started_at: datetime
    completed_at: Optional[datetime] = None
    duration: Optional[float] = None
    
    # 状态信息
    status: str = "pending"  # pending, in_progress, completed, failed
    success: bool = False
    error_message: Optional[str] = None
    
    # 影响评估
    affected_services: List[str] = field(default_factory=list)
    data_consistency_check: bool = True
    rollback_validation: bool = True
    
    # 用户信息
    initiated_by: str = "system"
    approved_by: Optional[str] = None
    
    # 元数据
    metadata: Dict[str, Any] = field(default_factory=dict)


class VersionManager:
    """版本管理器"""
    
    def __init__(self, config: Optional[RollbackConfig] = None):
        self.config = config or RollbackConfig()
        
        # 版本存储
        self.versions: Dict[str, VersionInfo] = {}
        self.current_version: Optional[str] = None
        self.stable_version: Optional[str] = None
        
        # 回滚记录
        self.rollback_records: Dict[str, RollbackRecord] = {}
        
        # 回滚状态
        self.is_rollback_in_progress = False
        self.last_rollback_time: Optional[datetime] = None
        
        # 回调函数
        self.rollback_callbacks: List[Callable] = []
        self.version_change_callbacks: List[Callable] = []
        
        # 锁
        self.lock = asyncio.Lock()
        
        # 存储目录
        self.storage_dir = Path("versions")
        self.storage_dir.mkdir(exist_ok=True)
        
        # 运行状态
        self.is_running = False
        self.monitoring_task: Optional[asyncio.Task] = None
        
        self.logger = logging.getLogger(__name__)
        self.logger.info("版本管理器已初始化")
    
    async def start(self) -> None:
        """启动版本管理器"""
        if self.is_running:
            return
        
        self.is_running = True
        
        # 加载现有版本
        await self._load_existing_versions()
        
        # 启动监控任务
        if self.config.enable_rollback_monitoring:
            self.monitoring_task = asyncio.create_task(self._monitoring_worker())
        
        self.logger.info("版本管理器已启动")
    
    async def stop(self) -> None:
        """停止版本管理器"""
        if not self.is_running:
            return
        
        self.is_running = False
        
        if self.monitoring_task:
            self.monitoring_task.cancel()
            try:
                await self.monitoring_task
            except asyncio.CancelledError:
                pass
        
        self.logger.info("版本管理器已停止")
    
    async def register_version(self, 
                              version_id: str,
                              version_name: str,
                              description: str = "",
                              git_commit: Optional[str] = None,
                              build_number: Optional[str] = None,
                              config_hash: Optional[str] = None,
                              dependencies: Optional[List[str]] = None) -> bool:
        """注册新版本"""
        async with self.lock:
            if version_id in self.versions:
                self.logger.warning(f"版本已存在: {version_id}")
                return False
            
            # 创建版本信息
            version_info = VersionInfo(
                version_id=version_id,
                version_name=version_name,
                description=description,
                git_commit=git_commit,
                build_number=build_number,
                build_time=datetime.now(timezone.utc),
                config_hash=config_hash,
                dependencies=dependencies or []
            )
            
            # 保存版本
            self.versions[version_id] = version_info
            await self._save_version_to_file(version_info)
            
            # 如果是第一个版本，设置为当前版本
            if not self.current_version:
                self.current_version = version_id
                version_info.status = VersionStatus.ACTIVE
            
            self.logger.info(f"版本注册成功: {version_id}")
            return True
    
    async def deploy_version(self, version_id: str) -> bool:
        """部署版本"""
        async with self.lock:
            if version_id not in self.versions:
                self.logger.warning(f"版本不存在: {version_id}")
                return False
            
            try:
                # 备份当前版本
                if self.current_version and self.config.enable_data_backup:
                    await self._backup_current_version()
                
                # 执行部署
                success = await self._execute_deployment(version_id)
                
                if success:
                    # 更新版本状态
                    old_version = self.current_version
                    self.current_version = version_id
                    
                    # 更新版本信息
                    version_info = self.versions[version_id]
                    version_info.status = VersionStatus.ACTIVE
                    version_info.deployed_at = datetime.now(timezone.utc)
                    
                    # 更新旧版本状态
                    if old_version and old_version in self.versions:
                        old_version_info = self.versions[old_version]
                        old_version_info.status = VersionStatus.DEPRECATED
                    
                    # 保存更改
                    await self._save_version_to_file(version_info)
                    if old_version:
                        await self._save_version_to_file(self.versions[old_version])
                    
                    # 触发版本变更回调
                    await self._trigger_version_change_callbacks(old_version, version_id)
                    
                    self.logger.info(f"版本部署成功: {version_id}")
                    return True
                else:
                    self.logger.error(f"版本部署失败: {version_id}")
                    return False
                
            except Exception as e:
                self.logger.error(f"版本部署异常: {version_id}, 错误: {e}")
                return False
    
    async def rollback_to_version(self, 
                                 target_version_id: str,
                                 strategy: Optional[RollbackStrategy] = None,
                                 trigger: RollbackTrigger = RollbackTrigger.MANUAL,
                                 reason: str = "",
                                 initiated_by: str = "system") -> str:
        """回滚到指定版本"""
        async with self.lock:
            # 检查回滚条件
            if not await self._can_rollback(target_version_id):
                raise ValueError(f"无法回滚到版本: {target_version_id}")
            
            # 生成回滚ID
            rollback_id = self._generate_rollback_id()
            
            # 创建回滚记录
            rollback_record = RollbackRecord(
                rollback_id=rollback_id,
                from_version=self.current_version or "unknown",
                to_version=target_version_id,
                strategy=strategy or self.config.default_strategy,
                trigger=trigger,
                reason=reason,
                started_at=datetime.now(timezone.utc),
                initiated_by=initiated_by
            )
            
            # 保存回滚记录
            self.rollback_records[rollback_id] = rollback_record
            await self._save_rollback_to_file(rollback_record)
            
            # 执行回滚
            try:
                self.is_rollback_in_progress = True
                rollback_record.status = "in_progress"
                
                success = await self._execute_rollback(rollback_record)
                
                rollback_record.status = "completed" if success else "failed"
                rollback_record.success = success
                rollback_record.completed_at = datetime.now(timezone.utc)
                rollback_record.duration = (rollback_record.completed_at - rollback_record.started_at).total_seconds()
                
                if success:
                    # 更新版本状态
                    await self._update_version_after_rollback(rollback_record)
                    self.last_rollback_time = datetime.now(timezone.utc)
                    
                    # 触发回滚回调
                    await self._trigger_rollback_callbacks(rollback_record)
                    
                    self.logger.info(f"回滚成功: {rollback_id}")
                else:
                    self.logger.error(f"回滚失败: {rollback_id}")
                
                # 保存回滚记录
                await self._save_rollback_to_file(rollback_record)
                
                return rollback_id
                
            except Exception as e:
                rollback_record.status = "failed"
                rollback_record.success = False
                rollback_record.error_message = str(e)
                rollback_record.completed_at = datetime.now(timezone.utc)
                
                await self._save_rollback_to_file(rollback_record)
                
                self.logger.error(f"回滚异常: {rollback_id}, 错误: {e}")
                raise
            
            finally:
                self.is_rollback_in_progress = False
    
    async def mark_version_as_stable(self, version_id: str) -> bool:
        """标记版本为稳定版本"""
        async with self.lock:
            if version_id not in self.versions:
                self.logger.warning(f"版本不存在: {version_id}")
                return False
            
            # 更新版本状态
            version_info = self.versions[version_id]
            version_info.is_stable = True
            version_info.status = VersionStatus.STABLE
            
            # 更新稳定版本
            self.stable_version = version_id
            
            # 保存更改
            await self._save_version_to_file(version_info)
            
            self.logger.info(f"版本标记为稳定: {version_id}")
            return True
    
    async def get_current_version(self) -> Optional[VersionInfo]:
        """获取当前版本"""
        if self.current_version:
            return self.versions.get(self.current_version)
        return None
    
    async def get_stable_version(self) -> Optional[VersionInfo]:
        """获取稳定版本"""
        if self.stable_version:
            return self.versions.get(self.stable_version)
        return None
    
    async def list_versions(self, 
                           status: Optional[VersionStatus] = None,
                           limit: int = 100) -> List[VersionInfo]:
        """列出版本"""
        versions = list(self.versions.values())
        
        if status:
            versions = [v for v in versions if v.status == status]
        
        # 按部署时间排序
        versions.sort(key=lambda v: v.deployed_at or v.created_at, reverse=True)
        
        return versions[:limit]
    
    async def get_rollback_history(self, limit: int = 50) -> List[RollbackRecord]:
        """获取回滚历史"""
        records = list(self.rollback_records.values())
        records.sort(key=lambda r: r.started_at, reverse=True)
        return records[:limit]
    
    async def _can_rollback(self, target_version_id: str) -> bool:
        """检查是否可以回滚"""
        # 检查版本是否存在
        if target_version_id not in self.versions:
            return False
        
        # 检查是否正在回滚
        if self.is_rollback_in_progress:
            return False
        
        # 检查冷却期
        if self.last_rollback_time:
            cooldown_end = self.last_rollback_time + timedelta(seconds=self.config.rollback_cooldown)
            if datetime.now(timezone.utc) < cooldown_end:
                return False
        
        # 检查回滚次数限制
        target_version = self.versions[target_version_id]
        if target_version.rollback_count >= self.config.max_rollback_attempts:
            return False
        
        return True
    
    async def _execute_rollback(self, rollback_record: RollbackRecord) -> bool:
        """执行回滚"""
        try:
            strategy = rollback_record.strategy
            
            if strategy == RollbackStrategy.IMMEDIATE:
                return await self._immediate_rollback(rollback_record)
            elif strategy == RollbackStrategy.GRADUAL:
                return await self._gradual_rollback(rollback_record)
            elif strategy == RollbackStrategy.CANARY:
                return await self._canary_rollback(rollback_record)
            elif strategy == RollbackStrategy.BLUE_GREEN:
                return await self._blue_green_rollback(rollback_record)
            else:
                self.logger.error(f"不支持的回滚策略: {strategy}")
                return False
        
        except Exception as e:
            self.logger.error(f"回滚执行失败: {e}")
            return False
    
    async def _immediate_rollback(self, rollback_record: RollbackRecord) -> bool:
        """立即回滚"""
        try:
            # 停止当前服务
            await self._stop_current_services()
            
            # 恢复目标版本
            await self._restore_version(rollback_record.to_version)
            
            # 启动服务
            await self._start_services()
            
            # 验证回滚
            if self.config.enable_data_validation:
                await self._validate_rollback(rollback_record)
            
            return True
        
        except Exception as e:
            self.logger.error(f"立即回滚失败: {e}")
            return False
    
    async def _gradual_rollback(self, rollback_record: RollbackRecord) -> bool:
        """逐步回滚"""
        try:
            # 逐步减少当前版本的流量
            # 这里可以实现更复杂的流量切换逻辑
            await self._immediate_rollback(rollback_record)
            return True
        
        except Exception as e:
            self.logger.error(f"逐步回滚失败: {e}")
            return False
    
    async def _canary_rollback(self, rollback_record: RollbackRecord) -> bool:
        """金丝雀回滚"""
        try:
            # 先在小部分流量上测试回滚版本
            # 如果成功，再逐步扩大
            await self._immediate_rollback(rollback_record)
            return True
        
        except Exception as e:
            self.logger.error(f"金丝雀回滚失败: {e}")
            return False
    
    async def _blue_green_rollback(self, rollback_record: RollbackRecord) -> bool:
        """蓝绿部署回滚"""
        try:
            # 在绿色环境中部署目标版本
            # 验证成功后切换流量
            await self._immediate_rollback(rollback_record)
            return True
        
        except Exception as e:
            self.logger.error(f"蓝绿回滚失败: {e}")
            return False
    
    async def _stop_current_services(self) -> None:
        """停止当前服务"""
        # 这里应该实现实际的服务停止逻辑
        self.logger.info("停止当前服务")
        await asyncio.sleep(1)  # 模拟停止时间
    
    async def _start_services(self) -> None:
        """启动服务"""
        # 这里应该实现实际的服务启动逻辑
        self.logger.info("启动服务")
        await asyncio.sleep(1)  # 模拟启动时间
    
    async def _restore_version(self, version_id: str) -> None:
        """恢复版本"""
        # 这里应该实现实际的版本恢复逻辑
        self.logger.info(f"恢复版本: {version_id}")
        await asyncio.sleep(2)  # 模拟恢复时间
    
    async def _validate_rollback(self, rollback_record: RollbackRecord) -> None:
        """验证回滚"""
        # 这里应该实现实际的回滚验证逻辑
        self.logger.info(f"验证回滚: {rollback_record.rollback_id}")
        await asyncio.sleep(1)  # 模拟验证时间
    
    async def _backup_current_version(self) -> None:
        """备份当前版本"""
        if not self.current_version:
            return
        
        backup_dir = self.storage_dir / "backups" / self.current_version
        backup_dir.mkdir(parents=True, exist_ok=True)
        
        # 这里应该实现实际的备份逻辑
        self.logger.info(f"备份当前版本: {self.current_version}")
    
    async def _update_version_after_rollback(self, rollback_record: RollbackRecord) -> None:
        """回滚后更新版本状态"""
        # 更新目标版本
        target_version = self.versions[rollback_record.to_version]
        target_version.status = VersionStatus.ACTIVE
        target_version.rollback_count += 1
        target_version.last_rollback_at = datetime.now(timezone.utc)
        target_version.rollback_reason = rollback_record.reason
        
        # 更新当前版本
        old_version = self.current_version
        self.current_version = rollback_record.to_version
        
        # 更新旧版本状态
        if old_version and old_version in self.versions:
            old_version_info = self.versions[old_version]
            old_version_info.status = VersionStatus.ROLLED_BACK
        
        # 保存更改
        await self._save_version_to_file(target_version)
        if old_version:
            await self._save_version_to_file(self.versions[old_version])
    
    async def _monitoring_worker(self) -> None:
        """监控工作线程"""
        while self.is_running:
            try:
                await self._check_rollback_conditions()
                await asyncio.sleep(60)  # 每分钟检查一次
            except asyncio.CancelledError:
                break
            except Exception as e:
                self.logger.error(f"监控任务异常: {e}")
                await asyncio.sleep(60)
    
    async def _check_rollback_conditions(self) -> None:
        """检查回滚条件"""
        if not self.config.enable_auto_rollback or not self.current_version:
            return
        
        current_version_info = self.versions[self.current_version]
        
        # 检查错误率
        if current_version_info.error_rate > self.config.error_rate_threshold:
            await self._trigger_auto_rollback(
                RollbackTrigger.ERROR_RATE,
                f"错误率过高: {current_version_info.error_rate:.2%}"
            )
            return
        
        # 检查响应时间
        if current_version_info.response_time > self.config.response_time_threshold:
            await self._trigger_auto_rollback(
                RollbackTrigger.RESPONSE_TIME,
                f"响应时间过长: {current_version_info.response_time:.2f}s"
            )
            return
    
    async def _trigger_auto_rollback(self, trigger: RollbackTrigger, reason: str) -> None:
        """触发自动回滚"""
        if not self.stable_version:
            self.logger.warning("没有稳定版本可用于自动回滚")
            return
        
        try:
            rollback_id = await self.rollback_to_version(
                target_version_id=self.stable_version,
                trigger=trigger,
                reason=reason,
                initiated_by="auto_rollback"
            )
            
            self.logger.info(f"自动回滚触发: {rollback_id}")
            
        except Exception as e:
            self.logger.error(f"自动回滚失败: {e}")
    
    def _generate_rollback_id(self) -> str:
        """生成回滚ID"""
        timestamp = int(time.time())
        return f"rollback_{timestamp}_{secrets.token_hex(4)}"
    
    async def _save_version_to_file(self, version_info: VersionInfo) -> None:
        """保存版本信息到文件"""
        version_file = self.storage_dir / f"version_{version_info.version_id}.json"
        
        version_data = {
            "version_id": version_info.version_id,
            "version_name": version_info.version_name,
            "description": version_info.description,
            "git_commit": version_info.git_commit,
            "build_number": version_info.build_number,
            "build_time": version_info.build_time.isoformat() if version_info.build_time else None,
            "deployed_at": version_info.deployed_at.isoformat() if version_info.deployed_at else None,
            "status": version_info.status.value,
            "is_stable": version_info.is_stable,
            "is_rollback_target": version_info.is_rollback_target,
            "config_hash": version_info.config_hash,
            "dependencies": version_info.dependencies,
            "error_rate": version_info.error_rate,
            "response_time": version_info.response_time,
            "throughput": version_info.throughput,
            "cpu_usage": version_info.cpu_usage,
            "memory_usage": version_info.memory_usage,
            "rollback_count": version_info.rollback_count,
            "last_rollback_at": version_info.last_rollback_at.isoformat() if version_info.last_rollback_at else None,
            "rollback_reason": version_info.rollback_reason,
            "tags": version_info.tags,
            "created_by": version_info.created_by,
            "created_at": version_info.created_at.isoformat()
        }
        
        with open(version_file, 'w') as f:
            json.dump(version_data, f, indent=2)
    
    async def _save_rollback_to_file(self, rollback_record: RollbackRecord) -> None:
        """保存回滚记录到文件"""
        rollback_file = self.storage_dir / f"rollback_{rollback_record.rollback_id}.json"
        
        rollback_data = {
            "rollback_id": rollback_record.rollback_id,
            "from_version": rollback_record.from_version,
            "to_version": rollback_record.to_version,
            "strategy": rollback_record.strategy.value,
            "trigger": rollback_record.trigger.value,
            "reason": rollback_record.reason,
            "started_at": rollback_record.started_at.isoformat(),
            "completed_at": rollback_record.completed_at.isoformat() if rollback_record.completed_at else None,
            "duration": rollback_record.duration,
            "status": rollback_record.status,
            "success": rollback_record.success,
            "error_message": rollback_record.error_message,
            "affected_services": rollback_record.affected_services,
            "data_consistency_check": rollback_record.data_consistency_check,
            "rollback_validation": rollback_record.rollback_validation,
            "initiated_by": rollback_record.initiated_by,
            "approved_by": rollback_record.approved_by,
            "metadata": rollback_record.metadata
        }
        
        with open(rollback_file, 'w') as f:
            json.dump(rollback_data, f, indent=2)
    
    async def _load_existing_versions(self) -> None:
        """加载现有版本"""
        try:
            for version_file in self.storage_dir.glob("version_*.json"):
                try:
                    with open(version_file, 'r') as f:
                        version_data = json.load(f)
                    
                    # 重建版本对象
                    version_info = VersionInfo(
                        version_id=version_data["version_id"],
                        version_name=version_data["version_name"],
                        description=version_data.get("description", ""),
                        git_commit=version_data.get("git_commit"),
                        build_number=version_data.get("build_number"),
                        build_time=datetime.fromisoformat(version_data["build_time"]) if version_data.get("build_time") else None,
                        deployed_at=datetime.fromisoformat(version_data["deployed_at"]) if version_data.get("deployed_at") else None,
                        status=VersionStatus(version_data.get("status", "active")),
                        is_stable=version_data.get("is_stable", False),
                        is_rollback_target=version_data.get("is_rollback_target", True),
                        config_hash=version_data.get("config_hash"),
                        dependencies=version_data.get("dependencies", []),
                        error_rate=version_data.get("error_rate", 0.0),
                        response_time=version_data.get("response_time", 0.0),
                        throughput=version_data.get("throughput", 0.0),
                        cpu_usage=version_data.get("cpu_usage", 0.0),
                        memory_usage=version_data.get("memory_usage", 0.0),
                        rollback_count=version_data.get("rollback_count", 0),
                        last_rollback_at=datetime.fromisoformat(version_data["last_rollback_at"]) if version_data.get("last_rollback_at") else None,
                        rollback_reason=version_data.get("rollback_reason", ""),
                        tags=version_data.get("tags", []),
                        created_by=version_data.get("created_by", "system"),
                        created_at=datetime.fromisoformat(version_data["created_at"])
                    )
                    
                    self.versions[version_info.version_id] = version_info
                    
                    # 设置当前版本和稳定版本
                    if version_info.status == VersionStatus.ACTIVE:
                        self.current_version = version_info.version_id
                    if version_info.is_stable:
                        self.stable_version = version_info.version_id
                
                except Exception as e:
                    self.logger.error(f"加载版本文件失败: {version_file}, 错误: {e}")
            
            self.logger.info(f"加载了 {len(self.versions)} 个版本")
        
        except Exception as e:
            self.logger.error(f"加载现有版本失败: {e}")
    
    async def _trigger_rollback_callbacks(self, rollback_record: RollbackRecord) -> None:
        """触发回滚回调"""
        for callback in self.rollback_callbacks:
            try:
                if asyncio.iscoroutinefunction(callback):
                    await callback(rollback_record)
                else:
                    callback(rollback_record)
            except Exception as e:
                self.logger.error(f"回滚回调执行失败: {e}")
    
    async def _trigger_version_change_callbacks(self, old_version: Optional[str], new_version: str) -> None:
        """触发版本变更回调"""
        for callback in self.version_change_callbacks:
            try:
                if asyncio.iscoroutinefunction(callback):
                    await callback(old_version, new_version)
                else:
                    callback(old_version, new_version)
            except Exception as e:
                self.logger.error(f"版本变更回调执行失败: {e}")
    
    def add_rollback_callback(self, callback: Callable) -> None:
        """添加回滚回调"""
        self.rollback_callbacks.append(callback)
    
    def add_version_change_callback(self, callback: Callable) -> None:
        """添加版本变更回调"""
        self.version_change_callbacks.append(callback)


# 全局版本管理器
_global_version_manager: Optional[VersionManager] = None


def get_version_manager() -> VersionManager:
    """获取全局版本管理器"""
    global _global_version_manager
    if _global_version_manager is None:
        _global_version_manager = VersionManager()
    return _global_version_manager
